<template>
	<view
		:style="{
			'--safe-area-bottom-height': setShowBottom ? setBottomHeight : '0px',
		}"
		class="my-layouts"
	>
		<!-- 固定头部内容 -->
		<view
			v-if="setShowTop"
			:style="[
				{
					background: topBackground,
					zIndex: topZIndex,
					height: setTopHeight,
				},
				topCustomStyle,
			]"
			class="my-layouts-top"
			@touchmove.stop.prevent
		>
			<slot name="top"></slot>
		</view>
		<!-- 视图滚动区域 -->
		<view
			:class="{ 'scroll-safe-area': setSafeAreaInsetBottom }"
			:style="setShowTop ? `padding-top:${setTopHeight}` : ''"
			class="my-layouts-scroll"
		>
			<slot name="scroll"></slot>
		</view>
		<!-- 底部安全区占位 -->
		<view
			:class="{
				'fixed-safe-area': setSafeAreaInsetBottom,
				transition: bottomTransition,
			}"
			:style="[
				{
					background: bottomBackground,
					zIndex: bottomZIndex,
				},
				bottomCustomStyle,
			]"
			class="my-layouts-bottom"
		>
			<slot v-if="setShowBottom" name="bottom"></slot>
		</view>
	</view>
</template>

<script>
export default {
	name: "my-layouts",
	props: {
		// 固定头部内容高度
		topHeight: {
			type: [Number, String],
			default: "0",
		},
		// 固定在头部的背景色
		topBackground: {
			type: String,
			default: "#fff",
		},
		// 固定在头部的层级
		topZIndex: {
			type: [Number, String],
			default: "200",
		},
		// 自定义头部样式
		topCustomStyle: {
			type: Object,
			default() {
				return {};
			},
		},
		// 固定在底部的层级
		bottomZIndex: {
			type: [Number, String],
			default: "200",
		},
		// 固定在底部的背景色
		bottomBackground: {
			type: String,
			default: "#fff",
		},
		// 固定底部内容高度
		bottomHeight: {
			type: [Number, String],
			default: "100",
		},
		// 是否需要开启安全区适配
		safeAreaInsetBottom: {
			type: Boolean,
			default: true,
		},
		// 是否显示固定头部内容
		showTop: {
			type: Boolean,
			default: true,
		},
		// 是否显示固定底部内容
		showBottom: {
			type: Boolean,
			default: true,
		},
		// 自定义固定底部样式
		bottomCustomStyle: {
			type: Object,
			default() {
				return {};
			},
		},
		// 是否需要底部高度变化的过渡效果
		bottomTransition: {
			type: Boolean,
			default: false,
		},
	},
	computed: {
		// 设置固定头部高度
		setTopHeight({ $utils, topHeight }) {
			return $utils.addUnit(topHeight);
		},
		// 设置固定底部高度
		setBottomHeight({ $utils, bottomHeight }) {
			let height = $utils.addUnit(bottomHeight);
			// 因为使用了css变量，所以要把rpx变成px
			if (height.includes("rpx")) {
				height = height.replace("rpx", "");
				height = uni.upx2px(height) + "px";
			}
			return height;
		},
		// 是否显示固定头部内容
		setShowTop({ showTop, setTopHeight, $slots }) {
			return showTop && parseInt(setTopHeight) > 0 && $slots["top"];
		},
		// 是否显示固定底部内容
		setShowBottom({ showBottom, setBottomHeight, $slots }) {
			return showBottom && parseInt(setBottomHeight) > 0 && $slots["bottom"];
		},
		// 动态设置安全区适配
		setSafeAreaInsetBottom({ safeAreaInsetBottom }) {
			try {
				const platform =
					uni.getSystemInfoSync() && uni.getSystemInfoSync().platform; // 获取设备类型
				return (
					safeAreaInsetBottom && (platform === "ios" || platform === "devtools")
				);
			} catch (e) {
				// 获取设备信息失败的话，默认不开启安全区适配
				return false;
			}
		},
	},
};
</script>

<style lang="scss" scoped>
.my-layouts {
	width: 100%;
}

// 滚动视图
.my-layouts-scroll {
	width: 100%;
	height: 100%;
	padding-bottom: var(--safe-area-bottom-height, 50px);
	&.scroll-safe-area {
		padding-bottom: calc(
			var(--safe-area-bottom-height, 50px) + constant(safe-area-inset-bottom)
		);
		padding-bottom: calc(
			var(--safe-area-bottom-height, 50px) + env(safe-area-inset-bottom)
		);
	}
}

// 固定头部视图
.my-layouts-top {
	position: fixed;
	top: 0;
	right: 0;
	left: 0;
	width: 100%;
}

// 固定底部视图
.my-layouts-bottom {
	position: fixed;
	right: 0;
	bottom: 0;
	left: 0;
	width: 100%;
	height: var(--safe-area-bottom-height, 50px);
	&.fixed-safe-area {
		height: calc(
			var(--safe-area-bottom-height, 50px) + constant(safe-area-inset-bottom)
		);
		height: calc(
			var(--safe-area-bottom-height, 50px) + env(safe-area-inset-bottom)
		);
		padding-bottom: constant(safe-area-inset-bottom);
		padding-bottom: env(safe-area-inset-bottom);
	}
	&.transition {
		transition: all 0.3s;
	}
}
</style>
